package com.wyh.service.serviceImpl.g3serviceimpl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyh.domain.dto.g3dto.G3OrganizationDto;
import com.wyh.domain.po.g3po.*;
import com.wyh.domain.vo.g3vo.AllChargeRateVO;
import com.wyh.domain.vo.g3vo.ChargeTypeVo;
import com.wyh.domain.vo.g3vo.PropertyManagementVO;
import com.wyh.mapper.g3mapper.G3ProjectMapper;
import com.wyh.service.g3service.AsyncService;
import com.wyh.service.g3service.IProjectService;
import com.wyh.utils.g3utils.ProjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * <p>
 * 项目表 服务实现类
 * </p>
 *
 * @author 唐书亮
 * @since 2024-05-21
 */
@Service("g3ProjectService")
public class ProjectServiceImpl extends ServiceImpl<G3ProjectMapper, G3Project> implements IProjectService {
    @Autowired
    private G3ProjectMapper g3ProjectMapper;
    @Autowired
    private AsyncService asyncService;

    @Override
    public PropertyManagementVO selectProject(G3OrganizationDto g3OrganizationDto) {
        // 参数校验放在方法最开始处
        if (ObjectUtils.isNull(g3OrganizationDto)) {
            throw new IllegalArgumentException("参数不能为空");
        }
        // 将时间封装进去
       ProjectUtils.encapsulationTime(g3OrganizationDto);
        Future<PropertyManagementVO> firstFuture = asyncService.selectFirst(g3OrganizationDto);
        Future<PropertyManagementVO> secondFuture =  asyncService.selectSecond(g3OrganizationDto);
        PropertyManagementVO result = null;
        PropertyManagementVO secondResult = null;
        try {
            // 使用get()获取结果，这里不需要再检查isDone()，因为前面allOf已经确保了完成
            result = firstFuture.get(3000l, TimeUnit.MILLISECONDS);
            secondResult = secondFuture.get(3000l, TimeUnit.MILLISECONDS);
        } catch (CompletionException e) {
            // 捕获CompletionException并记录日志
            log.error("First async task failed", e.getCause());
        } catch (InterruptedException e) {
            // 捕获InterruptedException并恢复中断状态
            log.error("First async task was interrupted", e);
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            // 捕获ExecutionException并记录日志
            log.error("Error retrieving result from first async task", e);
        } catch (TimeoutException e) {
            e.printStackTrace();
        }

        //将结果合并
        if (Objects.nonNull(result)&& Objects.nonNull(secondResult))
            BeanUtils.copyProperties(result, secondResult, "managedEstate", "customerCount", "houseCount", "managedArea");
        if (result == null) {
            return new PropertyManagementVO();
        }
        return result; // 如果两个任务都失败了，将返回null，根据实际情况可能需要调整为默认值或进行错误处理
    }

    @Override
    public ChargeTypeVo selectChargeType(G3OrganizationDto g3OrganizationDto) {
        if (ObjectUtils.isNull(g3OrganizationDto)) {
            throw new IllegalArgumentException("参数不能为空");
        }
        Future<ChargeTypeVo> chargeTypeVoFuture = asyncService.selectChargeType(g3OrganizationDto);
        try {
            return chargeTypeVoFuture.get(3000L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("First async task was interrupted", e);
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            log.error("Error retrieving result from first async task", e);
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<ChargeProjectRate> selectChargeRate(G3OrganizationDto g3OrganizationDto) {
        List<ChargeProjectRate> chargeProjectRates = new ArrayList<>();
        Future<List<ChargeProjectRate>> listFuture = asyncService.selectChargeRate(g3OrganizationDto);
        try {
            chargeProjectRates = listFuture.get(3000l, TimeUnit.MILLISECONDS);
            if (chargeProjectRates == null) {
                return  chargeProjectRates;
            }
            chargeProjectRates.forEach(chargeProjectRate -> {
                chargeProjectRate.setTotalRate(ProjectUtils.keepTwoDecimalPlaces(chargeProjectRate.getTotalRate()));
            });
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        return chargeProjectRates;
    }

    @Override
    public AllChargeRateVO selectAllChargeRate(G3OrganizationDto g3OrganizationDto) {
        Future<List<AllChargeRate>> listFuture = asyncService.selectAllChargeRate(g3OrganizationDto);
        AllChargeRateVO allChargeRateVO = new AllChargeRateVO(); // 初始化为非空值

        try {
            List<AllChargeRate> allChargeRateVOS = listFuture.get(3000L, TimeUnit.MILLISECONDS); // 调整超时时间为30秒

            if (allChargeRateVOS == null) {

                return allChargeRateVO; // 返回一个空的VO实例
            }

            // 对查询结果进行处理
            allChargeRateVOS.forEach(allChargeRate -> processAllChargeRate(allChargeRate));
            allChargeRateVO.setAllChargeRateVOList(allChargeRateVOS);
        }
        catch (InterruptedException e) {

            Thread.currentThread().interrupt(); // 重新设置中断状态
        }
        catch (TimeoutException e) {

        }
        catch (ExecutionException e) {

        }

        return allChargeRateVO;
    }



    private void processAllChargeRate(AllChargeRate allChargeRate) {
        Double value = allChargeRate.getTotalRate();
        if (value != null) { // 确保值不为空
            Double result = ProjectUtils.keepTwoDecimalPlaces(value);
            allChargeRate.setTotalRate(result);
        }
    }
    private void processAllChargeRate(ChargeProjectRate chargeRate) {
        Double value = chargeRate.getTotalRate();
        if (value != null) { // 确保值不为空
            Double result = ProjectUtils.keepTwoDecimalPlaces(value);
            chargeRate.setTotalRate(result);
        }
    }

    @Override
    public List<G3Project> findPark() {
        return g3ProjectMapper.findPark();
    }

    @Override
    public List<G3Project> findFloor() {
        return g3ProjectMapper.findFloor();
    }

    @Override
    public List<G3Organization> findorganization() {
        return g3ProjectMapper.findorganization();
    }



}
